<?php
namespace Modules\Activity\Entities\Fudai;

use Modules\Activity\Entities\BaseActivityModel;
use Illuminate\Database\Eloquent\Builder;
use Modules\Asset\Entities\Package;
use Modules\Activity\Entities\Fudai\Record;
use ThrowException;
use Setting;

use Stats;

// 一翻赏
class Activity extends BaseActivityModel
{
    protected $table = 'fudai_activity';

    public $activityType = 'fudai';
    public $activityTypeText = '福袋';
    // public $activityTypeText = '集卡';

    // protected $guarded = ['union_status', 'union_status_text', 'type_text'];

    // protected $appends = ['union_status', 'union_status_text'];

    protected $casts = [
        'tags' => 'json',
        'images' => 'json',
        'detail_images' => 'json',
        'sku_level' => 'json',
        'invite_rule' => 'json',
        'share_rule' => 'json',
        'multi_buy_discount' => 'json'
    ];

    public function getType($type) 
    {
        $map = [
            'base_sku_type' => 'fudai',
            'node_type' => 'fudai'
        ];

        return @$map[$type];
    }

    // 
    public function getNodeEntity()
    {
        return $this;
    }

    // 所有sku
    public function skus()
    {
        return $this->hasMany('\Modules\Activity\Entities\Fudai\Sku', 'activity_id')->orderBy('level', 'desc')->orderBy('list_weight', 'desc')->orderBy('id', 'desc');
    }

    public function getAllSkuLevel()
    {
        return $this->sku_level ?: [];
    }

    public function getOnStockLevel()
    {
        $skuLevel = $this->sku_level ?: [];

        return array_filter($skuLevel, function ($item) {
            return @$item['status'] == 1;
        });
        // return collect($this->sku_level ?: [])->where('status', 1);
    }

    // 获取某个等级的标题
    public function getLevelTitle($level)
    {
        $globalSetting = @Setting::get('sys_fudai_sku_level')['list'];
        $currentSetting = $this->getAllSkuLevel();

        // \Log::error($globalSetting);
        // \Log::error($currentSetting);
        $level -= 1;   // 下标由0开始

        return @$currentSetting[$level]['title'] ?: @$globalSetting[$level]['title'];
    }

    // 展示的奖品列表
    public function getDisplaySkus()
    {
        // skuLevel 设置
        $skuLevel = $this->sku_level ?: [];

        // 重组一下, 获取实时销量
        foreach ($skuLevel as $key => $level) {

            $index = $key + 1;
            $level['index'] = $index;  // 编号

            $level['odds_sum'] = $this->skus()->where('level', $index)->sum('odds');  // 库存
            
            $skuLevel[$key] = $level;
        }

        // 筛选
        $skuLevel = collect($skuLevel)->filter(function ($item) {
            return @$item['status'];
        });

        $luckyLevelIndexs = $skuLevel->pluck('index');

        // 幸运款包
        // $luckyLevel = pickLuckySku($skuLevel, 'odds', 1);

        // 返回在可抽奖等级内并且有库存的物品
        $skus = $this->skus()->whereIn('level', $luckyLevelIndexs)->onStock()->get();

        $skus->each(function ($sku) use ($skuLevel) {
            $level = $skuLevel->where('index', $sku->level)->first();
            $sku->total_odds = round(($sku->odds / $level['odds_sum']) * (@$level['odds'] ?: 0), 4);
        });

        return $skus;
    }

    // 取出可参与抽奖的物品
    public function getOnStockSkus($user = NULL)
    {
        // skuLevel 设置
        $skuLevel = $this->sku_level ?: [];

        // 此活动的总销量
        $allSales = $this->sales;

        // 重组一下, 获取实时销量
        foreach ($skuLevel as $key => $level) {

            $index = $key + 1;
            $level['index'] = $index;  // 编号
            $level['sales'] = $this->skus->where('level', $index)->sum('sales');  // 销量
            $level['stock'] = $this->skus->where('level', $index)->sum('stock');  // 库存
            $level['odds_sum'] = $this->skus->where('level', $index)->sum('odds');  // 库存

            if ($index === 1 && $level['stock'] === 0) {
                \Log::error('订单抽盒未完成~ 基础包没有了~');
                ThrowException::Conflict('已售罄~');
            }

            $skuLevel[$key] = $level;
        }

        // 筛选
        $skuLevel = collect($skuLevel)->filter(function ($item, $index) use ($allSales, $skuLevel) {

            if ($item['index'] === 1) {
                // 基础款包
                return true;
            }
            elseif ($item['index'] === 6) {
                return false;
            }
            elseif (@$item['status'] && @$item['stock']) {
                // 上架且有库存的款包, 判断是否超出预期概率
                // \Log::error(($item['sales'] / $allSales * 100) . ' ==> ' . $item['odds']);
                $currentOdds = $allSales ? ($item['sales'] / $allSales * 100) : 0;

                // 当前等级概率少于设置的概率
                if ($currentOdds < @$item['odds']) {

                    return true;
                }

            }

            // 其它情况禁用款包
            return false;
        });

        $skuLevel = $skuLevel->all();
        foreach ($skuLevel as $key => $level) {

            // 这里对所有符合以下条件的等级进行概率乘以1.6来增大出货概率以优化尾刀堆积问题
            // 1、非基础款等级
            // 2、等级实际出货概率小于设定的概率
            // $item['odds'] *= 1.6;
            if ($level['index'] !== 1) {
                $skuLevel[$key]['odds'] *=  1.6;
            }
        };
        $skuLevel = collect($skuLevel);

        // \Log::error($skuLevel);

        $luckyLevelIndexs = $skuLevel->pluck('index');

        // 幸运款包
        // $luckyLevel = pickLuckySku($skuLevel, 'odds', 1);

        // 返回在可抽奖等级内并且有库存的物品
        $skus = $this->skus()->whereIn('level', $luckyLevelIndexs)->onStock()->where('stock', '>', 0)->get();

        $skus->each(function ($sku) use ($skuLevel) {
            $level = $skuLevel->where('index', $sku->level)->first();
            $sku->total_odds = ($sku->odds / $level['odds_sum'] * 100) * $level['odds'];
        });


        // 增加回血池的奖品
        // 如果当前活动设置了回血线，且当前抽奖的用户已超出此线。 
        // 则需要从回血池中抽出贵重的物品添加到奖池中
        if ($this->min_lucky_score && $user && $user->stats) {

            // \Log::error($user->stats->fudai_pay_money_price - $user->stats->fudai_get_money_price);

            if ($user->lucky_score > $this->min_lucky_score) {
                // 随机取一件回血奖品加入到奖池中
                $tempSkus = $this->skus()->where('level', 6)->onStock()->where('stock', '>', 0)->inRandomOrder()->get();
                $sku = pickLuckySku($tempSkus, 'odds', 1);

                if ($sku) {
                    $sku->_cached_stock = 1;  // 只放1件到奖池
                    $sku->total_odds = 500000;   // 设置概率为500%
                    $skus->push($sku);
                }

                \Log::error('ID:' . $user->id . ' ' . $user->name . '已达到' . $this->min_lucky_score . '欧气值, 进入回血池' );
            }
        }

        // \Log::error('总概率' . $skus->sum('total_odds'));

        return $skus;
    }

    // 抽出幸运sku
    public function pickLuckySkus($total, $user = NULL, $order = NULL, $options = [])
    {
        // 所有可抽奖的福袋奖品
        $skus = $this->getOnStockSkus($user);

        // 等级的设置内容
        // $skuLevel = $this->sku_level;

        // 计算每个sku的最终概率 (等级概率 * 物品概率)
        // $skus->each(function ($sku) use ($skuLevel) {
        //     $sku->total_odds = $sku->odds * $skuLevel[$sku->level - 1]['odds'];
        // });

        // 抽出的幸运sku列表
        $luckyList = pickLuckySkuMaps($skus, 'total_odds', $total);

        if (!$luckyList) {
            \Log::error('订单抽盒未完成~' . @$order->number . ' 基础包没有了~');
            ThrowException::Conflict('已售罄~');
        }

        // 扣除库存
        if (!isset($options['add_sales']) || $options['add_sales']) {
            foreach ($luckyList as $skuMap) {
                if (!$skuMap['skuable']->addSales($skuMap['total'])) {
                   \Log::error('福袋抽盒库存不足 sku_id:' . $skuMap['skuable']->id);
                   ThrowException::Conflict('库存不足~');
                }
            }
        }

        // 重叠奖品是否拆分显示
        $repeatSkuMode = @Setting::get('sys_fudai_base')['repeat_sku_mode'];
        if ($repeatSkuMode === 'unbind') {

            $resList = [];

            foreach ($luckyList as $skuMap) {
                $total = $skuMap['total'];
                if ($total === 1) {
                    // 数量为1
                    array_push($resList, $skuMap);
                }
                else {
                    // 数量不为1，拆分多个
                    for ($i=0; $i<$total; $i++) {
                        $skuMap['total'] = 1;
                        array_push($resList, $skuMap);
                    }
                }
            }

            $luckyList = $resList;
        }

        return $luckyList;
    }

    // 试玩开sku
    public function pickLuckySkusForTry($total, $user = NULL, $order = NULL, $options = [])
    {
        // 取哪一个福袋
        // $skus = $this->skus()->where('level', '>', 3)->orderBy('level', 'desc')->orderBy('odds', 'asc')->onStock()->get();
        $skus = $this->getDisplaySkus()->where('level', '>', 1);

        if ($skus->count() === 0) {
            $skus = $this->getDisplaySkus();
        }

        // 虚拟库存
        $skus->each(function ($item) {
            $item->stock = 100;
        });

        // \Log::error($skus);

        $luckyList = pickLuckySkuMaps($skus, 'odds', $total);

        return $luckyList;
    }

    // 更新库存
    public function updateStock()
    {
        $this->update([
            'stock' => $this->skus()->sum('stock')
        ]);
    }

    // 检查是否超出限制
    static public function checkSaleLimit($total)
    {
        $setting = @Setting::get('sys_fudai_sale_limit') ?: [];
        if (@$setting['is_limit_every_day'] && @$setting['limit_total_every_day']) {
            $limitEveryDay = $setting['limit_total_every_day'];

            $todaySales = Package::where('node_type', 'fudai')->whereIn('status', [0, 1])->where('source_type',  1)->whereDate('created_at', date('Y-m-d'))->sum('sku_total');

            if ($todaySales + $total > $limitEveryDay) {
                if ($todaySales >= $limitEveryDay) {
                    ThrowException::Conflict('福袋今日已达到销售上限~');
                }
                else {
                    ThrowException::Conflict('福袋今日还可销售' . ($limitEveryDay - $todaySales) . '个~');
                }
            }
        }
        return true;
    }

    public function calcTotalList()
    {
        $arr = @Setting::get('sys_fudai_base')['custom_total'] ?: [
           [
                'total' => 1,
                'tips' => '',
                'title' => ''
           ],
           [
                'total' => 3,
                'tips' => '',
                'title' => ''
           ], 
           [
                'total' => 5,
                'tips' => '',
                'title' => ''
           ] 
        ];

        $totalList = [];
        foreach ($arr as $item) {
            $total = $item['total'];
            list($moneyDiscount, $scoreDiscount) = $this->calcMultiBuyDiscount($total);
            array_push($totalList, [
                'total' => $total,
                'tips' => @$item['tips'],
                'title' => @$item['title'] ?: '连开' . $total . '个',
                'is_discount' => $moneyDiscount || $scoreDiscount ? 1 : 0,
                'money_discount' => $moneyDiscount,
                'score_discount' => $scoreDiscount,
                'money_price' => getUnsignedNumber($this->money_price * $total - $moneyDiscount),
                'score_price' => getUnsignedNumber($this->score_price * $total - $scoreDiscount),
            ]);
        }

        return $totalList;
    }

    // 创建完package后的回调
    public function packageCreatedListenerSync($order, $package)
    {
        // 记录进榜单
        Record::createWith($package, $order, $this);
        
        // 更新开福袋统计
        Stats::updateWithPackageAndOrder($order->user, 'fudai', $package, $order);

    }
}
